package com.yanqu.road.server.gameplayer.module.player;

import com.yanqu.road.dao.impl.player.UserActivityRealRewardDaoImpl;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.player.UserActivityRealReward;
import com.yanqu.road.pb.activity.RealRewardProto;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.manger.DataAnalyticsMgr;
import com.yanqu.road.server.manger.activity.newyearbag.NewYearBagMgr;
import com.yanqu.road.server.manger.activity.signindraw.SignInDrawActivityMgr;
import com.yanqu.road.server.manger.maidian.DefaultEventTraceAction;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.string.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;

public class ActivityRealRewardModule extends GeneralModule {

    private Map<Integer, List<UserActivityRealReward>> realRewardMap = new ConcurrentHashMap<>();

    private Object lock = new Object();

    public ActivityRealRewardModule(GamePlayer player) {
        super(player);
    }

    public List<UserActivityRealReward> getUserRealRewardList(ActivityInfo activityInfo) {
        if(realRewardMap.containsKey(activityInfo.getActivityId())){
            return realRewardMap.get(activityInfo.getActivityId());
        }
        return new ArrayList<>();
    }

    /**
     * 添加实物奖励
     */
    public UserActivityRealReward addRealReward(int activityId, int goodsId, int num) {

        log.debug("user {} add activityId {} real reward goodsId {} num {}.", activityId, getUserId(), goodsId, num);

        synchronized (lock) {
            if(!realRewardMap.containsKey(activityId)){
                realRewardMap.put(activityId, new ArrayList<>());
            }
            List<UserActivityRealReward> userRealRewardList = realRewardMap.get(activityId);
            int maxNo = userRealRewardList.isEmpty() ? 0 : userRealRewardList.get(userRealRewardList.size() - 1).getNo();
            UserActivityRealReward userRealReward = new UserActivityRealReward();
            userRealReward.setUserId(getUserId());
            userRealReward.setNo(++maxNo);
            userRealReward.setGoodsId(goodsId);
            userRealReward.setNum(num);
            userRealReward.setGetTime(new Date());
            userRealReward.setAddrTime(new Date(0));
            userRealReward.setAddr("");
            userRealReward.setPhone("");
            userRealReward.setActivityId(activityId);
            userRealReward.setInsertOption();
            userRealRewardList.add(userRealReward);

            try {
                DefaultEventTraceAction action = new DefaultEventTraceAction("real_reward", player);
                action.build("activityid", activityId);
                action.build("real_rewardno", userRealReward.getNo());
                action.build("real_rewardid", goodsId);
                action.trace();
            }catch (Exception e){
                DataAnalyticsMgr.getLogger().error("", e);
            }
            return userRealReward;
        }
    }

    /**
     * 填写地址
     */
    public int setAddr(int activityId, int goodsId, String phone, String addr, int no) {
        // 检查格式
        if (!checkPhone(phone)) {
            return GameErrorCode.E_REAL_REWARD_PHONE_ERROR;
        }
        if (StringUtils.isNullOrEmpty(addr)) {
            return GameErrorCode.E_REAL_REWARD_NO_ADDR;
        }
        if(!realRewardMap.containsKey(activityId)){
            return GameErrorCode.E_REQUEST_ARGUMENT_ERROR;
        }

        List<UserActivityRealReward> userRealRewardList = realRewardMap.get(activityId);
        UserActivityRealReward realReward = null;
        if (no > 0) {
            // 指定NO填写
            for (int i = userRealRewardList.size() - 1; i >= 0; i--) {
                UserActivityRealReward tmp = userRealRewardList.get(i);
                if (tmp.getNo() == no) {
                    realReward = tmp;
                    break;
                }
            }
        } else {
            // 按最后获得的道具ID填写
            for (int i = userRealRewardList.size() - 1; i >= 0; i--) {
                UserActivityRealReward tmp = userRealRewardList.get(i);
                if (tmp.getGoodsId() == goodsId) {
                    realReward = tmp;
                    break;
                }
            }
        }
        if (realReward == null) {
            return GameErrorCode.E_REAL_REWARD_NO_EXIST;
        }
        if (realReward.getAddrTime().getTime() != 0) {
            return GameErrorCode.E_REAL_REWARD_HAD_SET_ADDR;
        }

        // 填写地址
        realReward.setPhone(phone);
        realReward.setAddr(addr);
        realReward.setAddrTime(new Date());


        try {
            DefaultEventTraceAction action = new DefaultEventTraceAction("real_rewardadd", player);
            action.build("activityid", activityId);
            action.build("real_rewardno", realReward.getNo());
            action.build("real_rewardid", goodsId);
            action.build("real_rewardaddr", realReward.getAddr());
            action.build("real_rewardphone", realReward.getPhone());
            action.trace();
        }catch (Exception e){
            DataAnalyticsMgr.getLogger().error("", e);
        }

        // 返回
        RealRewardProto.CommonDrawSetAddrRespMsg.Builder clientMsg = RealRewardProto.CommonDrawSetAddrRespMsg.newBuilder();
        clientMsg.setRet(0);
        clientMsg.setActivityId(realReward.getActivityId());
        RealRewardProto.CommonDrawRealRewardMsg.Builder builder = getBuilder(realReward);
        clientMsg.setRealRewardMsg(builder);
        player.sendPacket(Protocol.U_COMMON_DRAW_SET_ADDR, clientMsg);
        return 0;
    }


    public List<RealRewardProto.CommonDrawRealRewardMsg> getBuilder(List<UserActivityRealReward> realRewardList) {
        List<RealRewardProto.CommonDrawRealRewardMsg> list = new ArrayList<>();
        for (UserActivityRealReward realReward : realRewardList) {
            RealRewardProto.CommonDrawRealRewardMsg.Builder builder = getBuilder(realReward);
            list.add(builder.build());
        }
        return list;
    }

    public RealRewardProto.CommonDrawRealRewardMsg.Builder getBuilder(UserActivityRealReward realReward) {
        RealRewardProto.CommonDrawRealRewardMsg.Builder builder = RealRewardProto.CommonDrawRealRewardMsg.newBuilder();
        builder.setNo(realReward.getNo());
        builder.setGoodsId(realReward.getGoodsId());
        if (realReward.getAddrTime().getTime() != 0) {
            builder.setPhone(realReward.getPhone());
            builder.setAddr(realReward.getAddr());
            builder.setSubmitTime(realReward.getAddrTime().getTime());
        }
        return builder;
    }

    // 检查手机号
    private boolean checkPhone(String phone) {
        return Pattern.matches("^1\\d{10}$", phone);
    }

    @Override
    public boolean loadData() {

        List<Integer> activityIdList = new ArrayList<>();
        int activityId = SignInDrawActivityMgr.getActivityId();
        if(activityId > 0){
            activityIdList.add(activityId);
        }
        ActivityInfo activityInfo = NewYearBagMgr.getActivityInfo();
        if(activityInfo != null){
            activityIdList.add(activityInfo.getActivityId());
        }
        if(activityIdList.size() > 0) {
            realRewardMap = new UserActivityRealRewardDaoImpl().getUserActivityRealReward(activityIdList, getUserId());
        }
        return true;
    }

    @Override
    public boolean afterLoadData() {
        return true;
    }

    @Override
    public boolean saveData() {
        for (Map.Entry<Integer, List<UserActivityRealReward>> entry : realRewardMap.entrySet()) {
            List<UserActivityRealReward> userRealRewardList = entry.getValue();
            ArrayList<UserActivityRealReward> newList = new ArrayList<>(userRealRewardList);
            for (UserActivityRealReward data : newList) {
                if (data.isInsertOption()) {
                    new UserActivityRealRewardDaoImpl().add(data);
                } else if (data.isUpdateOption()) {
                    new UserActivityRealRewardDaoImpl().update(data);
                }
            }
        }
        return true;
    }
}
